﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace WatchDog.WatchItemManages
{
    public class WatchItemManage
    {
        private ConcurrentDictionary<int, WatchItem> _cache = new ConcurrentDictionary<int, WatchItem>();

        public delegate void DataChangedHandler(object sender, WatchItemChangedEventArgs e);
        public event DataChangedHandler DataChanged;

        public int LastHashCode { get; private set; }

        public List<WatchItem> GetAllWatchItems()
        {
            if (_cache.IsEmpty)
            {
                using var db = new SqliteDbContext();
                var list = db.QueryWatchItems.ToList();
                foreach (var fileInfo in list)
                {
                    _cache.AddOrUpdate(fileInfo.Id, fileInfo, (key, value) => value);
                }
                LastHashCode = list.GetHashCode();
                return list;
            }
            var list2 = _cache.Values.ToList();
            LastHashCode = list2.GetHashCode();
            return list2;
        }

        public void Add(WatchItem file)
        {
            using var db = new SqliteDbContext();
            file.LastUpdateTime = DateTime.Now;
            file.ConcurrencyStamp = Guid.NewGuid().ToString();
            db.WatchItems.Add(file);
            db.SaveChanges();

            _cache.Clear();
            DataChanged(this, new WatchItemChangedEventArgs(WatchItemChangedTypes.Add, new List<WatchItem>
                {
                    file
                }));
        }

        public void Del(int id)
        {
            using var db = new SqliteDbContext();
            var file = db.QueryWatchItems.FirstOrDefault(c => c.Id == id);
            if (file != null)
            {
                db.WatchItems.Remove(file);
                db.SaveChanges();

                _cache.Clear();

                DataChanged(this, new WatchItemChangedEventArgs(WatchItemChangedTypes.Del, new List<WatchItem>{
                        file
                    }));
            }
        }

        public void Update(int id, bool auto)
        {
            using var db = new SqliteDbContext();
            var model = db.QueryWatchItems.FirstOrDefault(c => c.Id == id);
            if (model != null)
            {
                model.AutoStart = auto;
                model.LastUpdateTime = DateTime.Now;
                model.ConcurrencyStamp = Guid.NewGuid().ToString(); 
                db.WatchItems.Update(model);
                db.SaveChanges();
                _cache.Clear();

                DataChanged(this, new WatchItemChangedEventArgs(WatchItemChangedTypes.Update, new List<WatchItem>
                    {
                        model
                    }));
            }
        }
        public void Update(WatchItem info)
        {
            using (var db = new SqliteDbContext())
            {
                var model = db.QueryWatchItems.FirstOrDefault(c => c.Id == info.Id);
                if (model != null)
                {
                    model.AutoStart = info.AutoStart;
                    model.DisplayName = info.DisplayName;
                    model.DelayStart = info.DelayStart;
                    model.FileName = info.FileName;
                    model.FilePath = info.FilePath;
                    model.Remark = info.Remark;
                    model.ScheduledRestart = info.ScheduledRestart;
                    model.LastUpdateTime = DateTime.Now;
                    model.ConcurrencyStamp = Guid.NewGuid().ToString();

                    db.WatchItems.Update(model);
                    db.SaveChanges();
                    _cache.Clear();

                    DataChanged(this, new WatchItemChangedEventArgs(WatchItemChangedTypes.Update, new List<WatchItem>
                {
                    model
                }));
                }
            }
        }

        public void ClearCache()
        {
            _cache.Clear();
        }
    }
}
